///*
// * To change this template, choose Tools | Templates
// * and open the template in the editor.
// */
//package spring;
//
//import java.awt.Color;
//import java.awt.Graphics2D;
//import java.awt.Point;
//import java.awt.Rectangle;
//import java.awt.RenderingHints;
//import java.awt.event.MouseAdapter;
//import java.awt.event.MouseEvent;
//import java.awt.image.BufferStrategy;
//import java.util.ArrayList;
//import java.util.concurrent.atomic.AtomicBoolean;
//import javax.swing.JFrame;
//import phys.Accelable;
//import phys.Force;
//import phys.Moveable;
//import phys.RK4;
//import vec.Point3f;
//import vec.Vector3f;
//
///**
// *
// * @author Vic
// */
//public class Main {
//
//    /**
//     * @param args the command line arguments
//     */
//    final static Point3f origen = new Point3f(400, 400, 0);
//    //final static Vector3f gravity = new Vector3f(5000, -5000, 0);
//
//    public static void main(String[] args) throws InterruptedException {
//        final ArrayList forces = new ArrayList<>();
////        springs.add(new Spring(50, 200, 1, new Point3f(origen.x + 200, origen.y - 200, origen.z)));
////        springs.add(new Spring(50, 200, 1, new Point3f(origen.x - 200, origen.y - 200, origen.z)));
////        springs.add(new Spring(50, 200, 1, new Point3f(origen.x - 200, origen.y + 200, origen.z)));
//        forces.add(new Spring(50, 200, 5, new Point3f(origen.x + 200, origen.y + 200, origen.z)));
//        Gravity grav = new Gravity(4e8f, 0);
//        grav.state.position = new Vector3f(origen);
//        //grav.state.position = new Vector3f(400, 400, 0);
//        forces.add(grav);
//        final Ball ball = new Ball(origen, new Rectangle((int) (origen.x - 800), (int) (origen.y - 800), 800, 800));
//
//        for (Object s : forces) {
//            ((Accelable) s).setState(ball.state);
//            ball.addForce((Force) s);
//        }
//        final JFrame frame = new JFrame();
//        final AtomicBoolean adjusting = new AtomicBoolean();
//        MouseAdapter ma = new MouseAdapter() {
//            int button = 0;
//
//            @Override
//            public void mouseDragged(MouseEvent e) {
//                Point point = e.getPoint();
//                point.y = (int) (2 * origen.y - point.y);
//                synchronized (forces) {
//                    if (button == MouseEvent.BUTTON1) {
//
//                        adjusting.set(true);
//                        if (Math.hypot(ball.state.position.x - point.x, ball.state.position.y - point.y) < 30) {
//                            adjusting.set(true);
//                            ball.state.position.x = point.x;
//                            ball.state.position.y = point.y;
//                        } else {
//                            for (Object s : forces) {
//                                if (((Moveable) s).collides(point)) {
//                                    adjusting.set(true);
//                                    ((Moveable) s).setPoistion(point.x, point.y);
//                                }
//                            }
//
//                        }
//                    }
//
//                }
//
//            }
//
//            @Override
//            public void mouseReleased(MouseEvent e) {
//                super.mouseReleased(e);
//                if (e.isPopupTrigger()) {
//                    popTrigger(e);
//                }
//                adjusting.set(false);
//            }
//
//            @Override
//            public void mousePressed(MouseEvent e) {
//                button = e.getButton();
//
//                if (e.isPopupTrigger()) {
//                    popTrigger(e);
//                } else {
//                    mouseMoved(e);
//                }
//            }
//
//            void popTrigger(MouseEvent e) {
//                Point point = e.getPoint();
//                point.y = (int) (2 * origen.y - point.y);
//                synchronized (forces) {
//
//                    Object toRemove = null;
//                    for (Object s : forces) {
//                        if (((Moveable) s).collides(point)) {
//                            adjusting.set(true);
//                            toRemove = s;
//                            break;
//                        }
//                    }
//                    if (toRemove != null) {
//                        ball.removeForce((Force) toRemove);
//                        forces.remove(toRemove);
//                    } else {
//                        switch (e.getClickCount()) {
//                            case 1:
//                                Spring spring = new Spring(50, 200, 1, new Point3f(point.x, point.y, 0));
//                                forces.add(spring);
//                                ball.addForce(spring);
//                                spring.state = ball.state;
//                                break;
//                            case 3:
//                                Gravity grav =new Gravity(-4e8f, 0);
//                                grav.state.position.x=point.x;
//                                grav.state.position.y=point.y;
//                                forces.add(grav);
//                                ball.addForce(grav);
//                                break;
//                            default:
//                                 grav =new Gravity(4e8f, 0);
//                                grav.state.position.x=point.x;
//                                grav.state.position.y=point.y;
//                                forces.add(grav);
//                                ball.addForce(grav);
//                        }
//                    }
//                }
//            }
//        };
//        frame.addMouseListener(ma);
//        frame.addMouseMotionListener(ma);
//
//        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        frame.setIgnoreRepaint(true);
//        frame.setSize(800, 800);
////        frame.setResizable(false);
//        //frame.pack();
//        frame.show();
//
//        frame.createBufferStrategy(2);
//        BufferStrategy bufferStrategy = frame.getBufferStrategy();
//        float startTime = System.nanoTime() / 1e9f;
//        float lastTime = 0;
//        float remaining = 0;
//        final float dt = 1 / 600f;
//        while (true) {
//            float currentTime = System.nanoTime() / 1e9f - startTime;
//            Graphics2D drawGraphics = (Graphics2D) bufferStrategy.getDrawGraphics();
//            //frame.paint(drawGraphics);
//
//            if (!adjusting.get()) {
//
//                remaining += (currentTime - lastTime);
//                System.out.println("remaining = " + 1/remaining);
//                int i = 0;
//                while (remaining > dt) {
//                    synchronized (forces) {
//                        RK4.integrate(ball, ball.state, currentTime, dt);
//                        remaining -= dt;
//                        currentTime += dt;
//
//                        i++;
//                        if (i % 20 == 0) {
//                            drawGraphics.setColor(Color.DARK_GRAY);
//
//                            drawGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//                            ball.draw(drawGraphics, origen, currentTime);
//                            for (Object s : forces) {
//                                ((Moveable) s).draw(drawGraphics, origen, currentTime);
//                            }
//                        }
//                    }
////                    
//                }
//
//            }
//            
//            drawGraphics.setPaint(new Color(255, 255, 255, 128));
//            drawGraphics.fillRect(0, 0, 800, 800);
//
//            drawGraphics.setColor(Color.black);
//            drawGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//            ball.draw(drawGraphics, origen, currentTime);
//            synchronized (forces) {
//                for (Object s : forces) {
//                    ((Moveable) s).draw(drawGraphics, origen, currentTime);
//                }
//            }
//
//            lastTime = currentTime;
//            
//            bufferStrategy.show();
//            drawGraphics.dispose();
//        }
//
//    }
//    
//}
